Skip to content
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

Avoid getting single call signatures when parameter types are the same #58392

Conversation

Andarist
Copy link
Contributor

@Andarist Andarist commented May 1, 2024

fixes #58391

@typescript-bot typescript-bot added the For Uncommitted Bug PR for untriaged, rejected, closed or missing bug label May 1, 2024
Copy link
Member

@ahejlsberg ahejlsberg left a comment

Choose a reason for hiding this comment

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

Just curious, did you determine which part of the skipped logic is actually causing the circularity?

@@ -20770,6 +20770,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
const sourceType = i === restIndex ? getRestOrAnyTypeAtPosition(source, i) : tryGetTypeAtPosition(source, i);
const targetType = i === restIndex ? getRestOrAnyTypeAtPosition(target, i) : tryGetTypeAtPosition(target, i);
if (sourceType && targetType) {
Copy link
Member

Choose a reason for hiding this comment

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

Change to sourceType && targetType && sourceType !== targetType and get rid of the conditional continue.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done :) thanks for pointing out

Comment on lines 20773 to 20775
if (sourceType === targetType) {
continue;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not super fond of this as a fix. It could be treated as a potential perf optimization~ - although I really doubt it would show anything in the perf runs, it's just an early bailout from this loop. It just happens to fix this particular circularity.

Similar bailouts are used in a couple of places in the code (even at the top of the containing function - compareSignaturesRelated).

Ideally, I'd just like to recognize this type as one without call signatures so it could be typechecked using regular rules. At first, I thought that this code could just be simplified for the scenarios with strictVariance - after all, if we already have strict variance on why do we need to special case anything here?

It turns out though that despite strict variance the callback parameters are still special - even if they are bivariant methods (!). This is somewhat surprising and I just learned about it today, while working on this but I guess it makes sense. Covariant type checking for callback parameters was introduced here. You can also see what changed when I tried to ignore this logic here

The problem arises on main because both getNonNullableType and getSingleCallSignature resolve properties of the type and both are called to learn if the parameter is a callback parameter.

In this specific case, I could also experiment with:

  • avoiding transitive resolveStructuredTypeMembers in getTypeFactsWorker based on callerOnlyNeeds. if the caller only needs to learn if the type is nullable or not... we don't need to check if it's a function type to compute those facts
  • avoiding resolveStructuredTypeMembers in getSingleSignature when SignatureKind.Call is requested and the type's symbol has a SymbolFlags.Class. If the type is a class then it has a construct signature (and thus getSingleCallSignature can't return true in such a case) so the code could bail out early.

Some extra consideration for unions/intersections could be put into the above too.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

cc @ahejlsberg - i was elaborating on this down here when u asked the question about what exact code has caused this ;p

@mikearnaldi
Copy link

Any idea if this will land in 5.5?

@jakebailey
Copy link
Member

@typescript-bot test it

@typescript-bot
Copy link
Collaborator

typescript-bot commented May 4, 2024

Starting jobs; this comment will be updated as builds start and complete.

Command Status Results
test top400 ✅ Started ✅ Results
user test this ✅ Started ✅ Results
run dt ✅ Started ✅ Results
perf test this faster ✅ Started 👀 Results

@typescript-bot
Copy link
Collaborator

Hey @jakebailey, the results of running the DT tests are ready.

Everything looks the same!

You can check the log here.

@typescript-bot
Copy link
Collaborator

@jakebailey Here are the results of running the user tests comparing main and refs/pull/58392/merge:

Everything looks good!

@typescript-bot
Copy link
Collaborator

@jakebailey
The results of the perf run you requested are in!

Here they are:

tsc

Comparison Report - baseline..pr
Metric baseline pr Delta Best Worst p-value
Compiler-Unions - node (v18.15.0, x64)
Errors 30 30 ~ ~ ~ p=1.000 n=6
Symbols 62,154 62,154 ~ ~ ~ p=1.000 n=6
Types 50,273 50,248 -25 (- 0.05%) ~ ~ p=0.001 n=6
Memory used 192,840k (± 0.76%) 192,934k (± 0.78%) ~ 192,145k 195,979k p=0.936 n=6
Parse Time 1.30s (± 0.69%) 1.29s (± 0.76%) ~ 1.28s 1.30s p=0.208 n=6
Bind Time 0.72s 0.72s ~ ~ ~ p=1.000 n=6
Check Time 9.53s (± 0.59%) 9.53s (± 0.36%) ~ 9.49s 9.59s p=0.686 n=6
Emit Time 2.63s (± 0.44%) 2.64s (± 0.63%) ~ 2.62s 2.66s p=0.183 n=6
Total Time 14.18s (± 0.43%) 14.18s (± 0.22%) ~ 14.13s 14.22s p=0.872 n=6
angular-1 - node (v18.15.0, x64)
Errors 5 5 ~ ~ ~ p=1.000 n=6
Symbols 945,322 944,110 -1,212 (- 0.13%) ~ ~ p=0.001 n=6
Types 408,110 407,141 -969 (- 0.24%) ~ ~ p=0.001 n=6
Memory used 1,222,771k (± 0.00%) 1,221,975k (± 0.00%) -796k (- 0.07%) 1,221,918k 1,222,037k p=0.005 n=6
Parse Time 8.10s (± 0.52%) 8.09s (± 0.40%) ~ 8.06s 8.13s p=0.629 n=6
Bind Time 2.24s (± 0.52%) 2.25s (± 0.47%) ~ 2.23s 2.26s p=0.279 n=6
Check Time 36.74s (± 0.62%) 36.29s (± 0.34%) -0.45s (- 1.22%) 36.11s 36.41s p=0.006 n=6
Emit Time 17.41s (± 0.40%) 17.41s (± 0.76%) ~ 17.24s 17.64s p=0.872 n=6
Total Time 64.48s (± 0.42%) 64.04s (± 0.33%) -0.45s (- 0.69%) 63.65s 64.22s p=0.031 n=6
mui-docs - node (v18.15.0, x64)
Errors 5 5 ~ ~ ~ p=1.000 n=6
Symbols 1,957,132 1,956,350 -782 (- 0.04%) ~ ~ p=0.001 n=6
Types 676,640 676,096 -544 (- 0.08%) ~ ~ p=0.001 n=6
Memory used 1,765,549k (± 0.00%) 1,765,034k (± 0.00%) -514k (- 0.03%) 1,764,997k 1,765,057k p=0.005 n=6
Parse Time 6.70s (± 0.21%) 6.70s (± 0.21%) ~ 6.68s 6.72s p=0.510 n=6
Bind Time 2.32s 2.31s (± 0.36%) ~ 2.30s 2.32s p=0.176 n=6
Check Time 56.26s (± 0.35%) 56.25s (± 0.32%) ~ 56.00s 56.51s p=0.936 n=6
Emit Time 0.14s 0.14s ~ ~ ~ p=1.000 n=6
Total Time 65.41s (± 0.30%) 65.41s (± 0.26%) ~ 65.17s 65.64s p=0.810 n=6
self-build-src - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 1,217,388 1,216,454 -934 (- 0.08%) ~ ~ p=0.001 n=6
Types 259,008 258,353 -655 (- 0.25%) ~ ~ p=0.001 n=6
Memory used 2,328,352k (± 0.04%) 2,326,236k (± 0.02%) -2,117k (- 0.09%) 2,325,748k 2,327,139k p=0.005 n=6
Parse Time 4.93s (± 0.94%) 4.98s (± 0.98%) ~ 4.90s 5.04s p=0.149 n=6
Bind Time 1.88s (± 0.64%) 1.87s (± 0.62%) ~ 1.86s 1.89s p=0.507 n=6
Check Time 33.42s (± 0.31%) 33.56s (± 0.20%) ~ 33.50s 33.68s p=0.078 n=6
Emit Time 2.57s (± 3.06%) 2.63s (± 1.31%) ~ 2.60s 2.69s p=0.065 n=6
Total Time 42.81s (± 0.33%) 43.05s (± 0.18%) +0.24s (+ 0.55%) 42.96s 43.16s p=0.020 n=6
self-build-src-public-api - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 1,217,388 1,216,454 -934 (- 0.08%) ~ ~ p=0.001 n=6
Types 259,008 258,353 -655 (- 0.25%) ~ ~ p=0.001 n=6
Memory used 2,402,962k (± 0.02%) 2,402,012k (± 0.01%) -950k (- 0.04%) 2,401,571k 2,402,311k p=0.005 n=6
Parse Time 5.14s (± 1.52%) 5.12s (± 0.57%) ~ 5.09s 5.16s p=0.521 n=6
Bind Time 1.68s (± 1.02%) 1.68s (± 0.62%) ~ 1.67s 1.70s p=1.000 n=6
Check Time 34.04s (± 0.21%) 34.05s (± 0.33%) ~ 33.92s 34.18s p=0.936 n=6
Emit Time 2.63s (± 0.57%) 2.62s (± 0.99%) ~ 2.58s 2.65s p=0.936 n=6
Total Time 43.50s (± 0.15%) 43.50s (± 0.26%) ~ 43.37s 43.63s p=1.000 n=6
self-compiler - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 256,310 256,071 -239 (- 0.09%) ~ ~ p=0.001 n=6
Types 104,458 104,168 -290 (- 0.28%) ~ ~ p=0.001 n=6
Memory used 424,929k (± 0.01%) 424,726k (± 0.01%) -203k (- 0.05%) 424,681k 424,769k p=0.005 n=6
Parse Time 4.15s (± 0.58%) 4.15s (± 0.83%) ~ 4.09s 4.19s p=0.568 n=6
Bind Time 1.58s (± 0.86%) 1.58s (± 1.57%) ~ 1.55s 1.62s p=0.515 n=6
Check Time 21.86s (± 0.24%) 21.89s (± 0.37%) ~ 21.79s 22.03s p=0.688 n=6
Emit Time 1.71s (± 1.86%) 1.72s (± 1.26%) ~ 1.69s 1.75s p=0.809 n=6
Total Time 29.30s (± 0.30%) 29.35s (± 0.25%) ~ 29.25s 29.46s p=0.575 n=6
ts-pre-modules - node (v18.15.0, x64)
Errors 35 35 ~ ~ ~ p=1.000 n=6
Symbols 224,826 224,575 -251 (- 0.11%) ~ ~ p=0.001 n=6
Types 94,115 93,785 -330 (- 0.35%) ~ ~ p=0.001 n=6
Memory used 369,973k (± 0.04%) 369,763k (± 0.03%) -209k (- 0.06%) 369,659k 369,903k p=0.013 n=6
Parse Time 3.49s (± 0.78%) 3.52s (± 0.51%) ~ 3.50s 3.54s p=0.089 n=6
Bind Time 1.94s (± 0.42%) 1.93s (± 1.20%) ~ 1.91s 1.97s p=0.217 n=6
Check Time 19.33s (± 0.28%) 19.24s (± 0.56%) ~ 19.14s 19.44s p=0.065 n=6
Emit Time 0.00s 0.00s ~ ~ ~ p=1.000 n=6
Total Time 24.77s (± 0.28%) 24.69s (± 0.45%) ~ 24.60s 24.90s p=0.128 n=6
vscode - node (v18.15.0, x64)
Errors 4 4 ~ ~ ~ p=1.000 n=6
Symbols 2,804,835 2,804,006 -829 (- 0.03%) ~ ~ p=0.001 n=6
Types 952,327 951,775 -552 (- 0.06%) ~ ~ p=0.001 n=6
Memory used 2,976,940k (± 0.00%) 2,976,394k (± 0.00%) -545k (- 0.02%) 2,976,275k 2,976,505k p=0.005 n=6
Parse Time 13.76s (± 0.31%) 13.77s (± 0.14%) ~ 13.74s 13.80s p=1.000 n=6
Bind Time 4.11s (± 0.40%) 4.10s (± 0.30%) ~ 4.09s 4.12s p=1.000 n=6
Check Time 72.76s (± 0.30%) 72.53s (± 0.31%) ~ 72.22s 72.92s p=0.128 n=6
Emit Time 23.63s (± 0.79%) 23.67s (± 0.31%) ~ 23.59s 23.77s p=1.000 n=6
Total Time 114.27s (± 0.27%) 114.09s (± 0.20%) ~ 113.76s 114.41s p=0.230 n=6
webpack - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 265,864 265,792 -72 (- 0.03%) ~ ~ p=0.001 n=6
Types 108,449 108,393 -56 (- 0.05%) ~ ~ p=0.001 n=6
Memory used 410,456k (± 0.02%) 410,450k (± 0.03%) ~ 410,335k 410,590k p=0.810 n=6
Parse Time 4.77s (± 0.65%) 4.77s (± 0.43%) ~ 4.75s 4.80s p=0.418 n=6
Bind Time 2.08s (± 1.08%) 2.07s (± 1.31%) ~ 2.02s 2.10s p=0.935 n=6
Check Time 20.96s (± 0.24%) 20.97s (± 0.56%) ~ 20.84s 21.11s p=1.000 n=6
Emit Time 0.00s 0.00s ~ ~ ~ p=1.000 n=6
Total Time 27.80s (± 0.21%) 27.81s (± 0.44%) ~ 27.69s 27.96s p=1.000 n=6
xstate-main - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 524,146 523,762 -384 (- 0.07%) ~ ~ p=0.001 n=6
Types 178,737 178,516 -221 (- 0.12%) ~ ~ p=0.001 n=6
Memory used 462,180k (± 0.01%) 461,913k (± 0.02%) -267k (- 0.06%) 461,769k 462,037k p=0.005 n=6
Parse Time 3.89s (± 0.57%) 3.88s (± 0.35%) ~ 3.87s 3.91s p=0.508 n=6
Bind Time 1.47s (± 1.27%) 1.47s (± 1.25%) ~ 1.45s 1.50s p=1.000 n=6
Check Time 22.47s (± 0.59%) 22.38s (± 0.64%) ~ 22.15s 22.57s p=0.335 n=6
Emit Time 0.00s 0.00s ~ ~ ~ p=1.000 n=6
Total Time 27.83s (± 0.45%) 27.74s (± 0.43%) ~ 27.56s 27.92s p=0.298 n=6
System info unknown
Hosts
  • node (v18.15.0, x64)
Scenarios
  • Compiler-Unions - node (v18.15.0, x64)
  • angular-1 - node (v18.15.0, x64)
  • mui-docs - node (v18.15.0, x64)
  • self-build-src - node (v18.15.0, x64)
  • self-build-src-public-api - node (v18.15.0, x64)
  • self-compiler - node (v18.15.0, x64)
  • ts-pre-modules - node (v18.15.0, x64)
  • vscode - node (v18.15.0, x64)
  • webpack - node (v18.15.0, x64)
  • xstate-main - node (v18.15.0, x64)
Benchmark Name Iterations
Current pr 6
Baseline baseline 6

Developer Information:

Download Benchmarks

@typescript-bot
Copy link
Collaborator

@jakebailey Here are the results of running the top 400 repos comparing main and refs/pull/58392/merge:

Everything looks good!

@RyanCavanaugh RyanCavanaugh merged commit 9598d35 into microsoft:main May 6, 2024
28 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
For Uncommitted Bug PR for untriaged, rejected, closed or missing bug
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Surprising circularity when parameter within base type expression refers to the class itself
6 participants