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

Instantiate earlier inferred constraints in conditional types #57362

Conversation

Andarist
Copy link
Contributor

@Andarist Andarist commented Feb 9, 2024

fixes #57286 (comment)

some historical related context can be found in #31455 and #42747

@jakebailey
Copy link
Member

@typescript-bot test top200
@typescript-bot user test this
@typescript-bot run dt

@typescript-bot perf test this faster

@typescript-bot
Copy link
Collaborator

typescript-bot commented Feb 9, 2024

Heya @jakebailey, I've started to run the diff-based user code test suite on this PR at 1148bce. You can monitor the build here.

Update: The results are in!

@typescript-bot
Copy link
Collaborator

typescript-bot commented Feb 9, 2024

Heya @jakebailey, I've started to run the parallelized Definitely Typed test suite on this PR at 1148bce. You can monitor the build here.

Update: The results are in!

@typescript-bot
Copy link
Collaborator

typescript-bot commented Feb 9, 2024

Heya @jakebailey, I've started to run the faster perf test suite on this PR at 1148bce. You can monitor the build here.

Update: The results are in!

@typescript-bot
Copy link
Collaborator

typescript-bot commented Feb 9, 2024

Heya @jakebailey, I've started to run the diff-based top-repos suite on this PR at 1148bce. You can monitor the build here.

Update: The results are in!

// * The original `mapper` used to create this conditional
// * The mapper that maps the old root type parameter to the clone (`freshMapper`)
// * The mapper that maps the clone to its inference result (`context.mapper`)
const freshParams = sameMap(root.inferTypeParameters, maybeCloneTypeParameter);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This PR - in its current form - removes the context of those fresh params.

They were introduced in this PR to address a type parameter leak. From what I understand, the leak was caused by non-instantiated constraints of infer type parameters, and those fresh params were introduced to "wire up" the mapper so it would partake in the instantiation of those constraints. Those instantiations are made using context.nonFixingMapper so I figured out that maybe this can be simplified by combining that with the mapper.

The problem with maybeCloneTypeParameter that was used to create those freshParams is that the check inside it is non-exhaustive:

isGenericObjectType(constraint) || isGenericIndexType(constraint)

When it comes to the added test case, this check doesn't cover Klass<V> - that's neither of the tested things. (when the inferred Klass<number> gets checked against that constraint it fails the assignability check and the inferred result gets replaced by the constraint which in turn is instantiated by the combinedMapper)

So the alternative fix would be to extend this check to cover more situations. That can't be done exhaustively and cheaply. The closest check to that is couldContainTypeVariables and that's not supposed to be used in situations like this, it's just an optimization.

So given the fact above, one extra alternative solution comes to mind... freshParams could always be created. I verified that it would fix the issue and that it wouldn't break any existing case.

@typescript-bot
Copy link
Collaborator

@jakebailey Here are the results of running the user test suite comparing main and refs/pull/57362/merge:

There were infrastructure failures potentially unrelated to your change:

  • 1 instance of "Package install failed"

Otherwise...

Something interesting changed - please have a look.

Details

puppeteer

packages/browsers/test/src/tsconfig.json

@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
Angular - node (v18.15.0, x64)
Memory used 295,672k (± 0.01%) 295,669k (± 0.01%) ~ 295,637k 295,721k p=0.810 n=6
Parse Time 2.66s (± 0.24%) 2.65s (± 0.55%) ~ 2.63s 2.67s p=0.345 n=6
Bind Time 0.82s (± 0.66%) 0.83s (± 1.92%) ~ 0.81s 0.85s p=0.498 n=6
Check Time 8.21s (± 0.23%) 8.20s (± 0.23%) ~ 8.18s 8.23s p=0.807 n=6
Emit Time 7.10s (± 0.24%) 7.09s (± 0.29%) ~ 7.06s 7.11s p=0.806 n=6
Total Time 18.79s (± 0.17%) 18.78s (± 0.13%) ~ 18.74s 18.81s p=0.333 n=6
Compiler-Unions - node (v18.15.0, x64)
Memory used 193,500k (± 1.55%) 193,897k (± 1.47%) ~ 191,464k 197,360k p=1.000 n=6
Parse Time 1.35s (± 0.47%) 1.36s (± 0.55%) ~ 1.35s 1.37s p=0.081 n=6
Bind Time 0.72s (± 0.00%) 0.72s (± 0.00%) ~ 0.72s 0.72s p=1.000 n=6
Check Time 9.37s (± 0.55%) 9.37s (± 0.24%) ~ 9.34s 9.40s p=0.872 n=6
Emit Time 2.62s (± 0.66%) 2.61s (± 0.59%) ~ 2.59s 2.63s p=0.461 n=6
Total Time 14.06s (± 0.29%) 14.06s (± 0.12%) ~ 14.03s 14.08s p=0.808 n=6
Monaco - node (v18.15.0, x64)
Memory used 347,464k (± 0.00%) 347,467k (± 0.01%) ~ 347,436k 347,488k p=0.574 n=6
Parse Time 2.48s (± 0.72%) 2.47s (± 0.33%) ~ 2.46s 2.48s p=0.324 n=6
Bind Time 0.93s (± 0.56%) 0.92s (± 0.56%) ~ 0.92s 0.93s p=0.311 n=6
Check Time 6.95s (± 0.37%) 6.94s (± 0.30%) ~ 6.92s 6.98s p=0.418 n=6
Emit Time 4.06s (± 0.61%) 4.07s (± 0.55%) ~ 4.03s 4.09s p=0.684 n=6
Total Time 14.42s (± 0.16%) 14.40s (± 0.24%) ~ 14.34s 14.44s p=0.462 n=6
TFS - node (v18.15.0, x64)
Memory used 302,857k (± 0.00%) 302,849k (± 0.00%) ~ 302,824k 302,861k p=0.422 n=6
Parse Time 2.02s (± 0.73%) 2.02s (± 0.52%) ~ 2.01s 2.04s p=0.805 n=6
Bind Time 1.00s (± 0.81%) 1.00s (± 0.98%) ~ 0.99s 1.02s p=0.673 n=6
Check Time 6.34s (± 0.44%) 6.34s (± 0.41%) ~ 6.30s 6.37s p=0.936 n=6
Emit Time 3.60s (± 0.38%) 3.60s (± 0.42%) ~ 3.59s 3.63s p=1.000 n=6
Total Time 12.96s (± 0.24%) 12.97s (± 0.30%) ~ 12.91s 13.00s p=0.935 n=6
material-ui - node (v18.15.0, x64)
Memory used 511,369k (± 0.00%) 511,378k (± 0.01%) ~ 511,346k 511,421k p=0.689 n=6
Parse Time 2.64s (± 0.66%) 2.65s (± 0.62%) ~ 2.63s 2.67s p=0.281 n=6
Bind Time 0.99s (± 0.55%) 1.00s (± 0.82%) ~ 0.99s 1.01s p=0.859 n=6
Check Time 17.25s (± 0.33%) 17.34s (± 0.43%) ~ 17.25s 17.43s p=0.054 n=6
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) ~ 0.00s 0.00s p=1.000 n=6
Total Time 20.88s (± 0.29%) 20.99s (± 0.41%) +0.11s (+ 0.53%) 20.87s 21.09s p=0.045 n=6
mui-docs - node (v18.15.0, x64)
Memory used 2,269,547k (± 0.00%) 2,269,595k (± 0.00%) +48k (+ 0.00%) 2,269,565k 2,269,627k p=0.010 n=6
Parse Time 11.86s (± 0.61%) 11.92s (± 0.73%) ~ 11.86s 12.09s p=0.092 n=6
Bind Time 2.64s (± 0.32%) 2.65s (± 0.32%) ~ 2.63s 2.65s p=0.084 n=6
Check Time 101.19s (± 0.63%) 101.04s (± 0.58%) ~ 100.33s 101.66s p=0.689 n=6
Emit Time 0.32s (± 1.28%) 0.32s (± 1.28%) ~ 0.31s 0.32s p=1.000 n=6
Total Time 116.01s (± 0.55%) 115.93s (± 0.45%) ~ 115.26s 116.53s p=0.936 n=6
self-build-src - node (v18.15.0, x64)
Memory used 2,414,079k (± 0.01%) 2,413,593k (± 0.01%) -486k (- 0.02%) 2,413,304k 2,413,888k p=0.013 n=6
Parse Time 4.94s (± 1.01%) 4.91s (± 0.30%) ~ 4.89s 4.92s p=0.422 n=6
Bind Time 1.88s (± 1.00%) 1.86s (± 0.65%) ~ 1.84s 1.87s p=0.104 n=6
Check Time 33.39s (± 0.22%) 33.32s (± 0.25%) ~ 33.16s 33.38s p=0.229 n=6
Emit Time 2.70s (± 1.60%) 2.66s (± 0.63%) -0.04s (- 1.42%) 2.65s 2.69s p=0.044 n=6
Total Time 42.92s (± 0.20%) 42.77s (± 0.20%) -0.15s (- 0.35%) 42.60s 42.81s p=0.008 n=6
self-compiler - node (v18.15.0, x64)
Memory used 418,763k (± 0.01%) 418,795k (± 0.01%) ~ 418,708k 418,896k p=0.230 n=6
Parse Time 2.79s (± 2.62%) 2.82s (± 2.99%) ~ 2.66s 2.89s p=0.166 n=6
Bind Time 1.10s (± 4.91%) 1.11s (± 5.54%) ~ 1.08s 1.23s p=0.599 n=6
Check Time 15.10s (± 0.20%) 15.11s (± 0.24%) ~ 15.05s 15.16s p=0.933 n=6
Emit Time 1.14s (± 0.90%) 1.13s (± 0.91%) ~ 1.12s 1.15s p=0.134 n=6
Total Time 20.14s (± 0.16%) 20.17s (± 0.13%) ~ 20.13s 20.20s p=0.107 n=6
vscode - node (v18.15.0, x64)
Memory used 2,828,957k (± 0.00%) 2,828,985k (± 0.00%) ~ 2,828,940k 2,829,025k p=0.336 n=6
Parse Time 10.74s (± 0.54%) 10.71s (± 0.39%) ~ 10.67s 10.77s p=0.421 n=6
Bind Time 3.42s (± 0.16%) 3.43s (± 0.44%) ~ 3.41s 3.45s p=0.865 n=6
Check Time 59.83s (± 0.49%) 60.07s (± 0.45%) ~ 59.74s 60.47s p=0.128 n=6
Emit Time 16.24s (± 0.21%) 16.18s (± 0.31%) ~ 16.11s 16.24s p=0.076 n=6
Total Time 90.23s (± 0.35%) 90.39s (± 0.30%) ~ 90.04s 90.79s p=0.298 n=6
webpack - node (v18.15.0, x64)
Memory used 393,995k (± 0.01%) 393,973k (± 0.01%) ~ 393,923k 394,044k p=0.378 n=6
Parse Time 3.10s (± 0.56%) 3.11s (± 0.57%) ~ 3.08s 3.13s p=0.255 n=6
Bind Time 1.38s (± 1.25%) 1.38s (± 1.06%) ~ 1.37s 1.40s p=0.933 n=6
Check Time 14.06s (± 0.16%) 14.03s (± 0.14%) ~ 14.00s 14.05s p=0.063 n=6
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) ~ 0.00s 0.00s p=1.000 n=6
Total Time 18.54s (± 0.17%) 18.52s (± 0.19%) ~ 18.46s 18.56s p=0.572 n=6
xstate - node (v18.15.0, x64)
Memory used 513,391k (± 0.01%) 513,417k (± 0.01%) ~ 513,342k 513,480k p=0.297 n=6
Parse Time 3.27s (± 0.19%) 3.28s (± 0.25%) ~ 3.27s 3.29s p=0.177 n=6
Bind Time 1.54s (± 0.41%) 1.54s (± 0.35%) ~ 1.54s 1.55s p=0.201 n=6
Check Time 2.86s (± 0.94%) 2.85s (± 0.62%) ~ 2.84s 2.89s p=0.288 n=6
Emit Time 0.08s (± 5.21%) 0.08s (± 4.99%) ~ 0.08s 0.09s p=0.218 n=6
Total Time 7.76s (± 0.34%) 7.76s (± 0.29%) ~ 7.74s 7.80s p=0.872 n=6
System info unknown
Hosts
  • node (v18.15.0, x64)
Scenarios
  • Angular - node (v18.15.0, x64)
  • Compiler-Unions - node (v18.15.0, x64)
  • Monaco - node (v18.15.0, x64)
  • TFS - node (v18.15.0, x64)
  • material-ui - node (v18.15.0, x64)
  • mui-docs - node (v18.15.0, x64)
  • self-build-src - node (v18.15.0, x64)
  • self-compiler - node (v18.15.0, x64)
  • vscode - node (v18.15.0, x64)
  • webpack - node (v18.15.0, x64)
  • xstate - node (v18.15.0, x64)
Benchmark Name Iterations
Current pr 6
Baseline baseline 6

Developer Information:

Download Benchmarks

@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 top-repos suite comparing main and refs/pull/57362/merge:

Everything looks good!

Copy link
Member

@weswigham weswigham left a comment

Choose a reason for hiding this comment

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

IIRC, I added the maybeCloneTypeParameters bit back when it was supposed that the type identities produced here could be bad for perf. Well, we have much better perf tests now, and they look fine to me, so I think this is pretty fine. Now, there may be some edge case that it effects in an outsized way, but hopefully if/when that comes up, we can come up with something nicer to make that work out, because this has always been a bit off-putting to me.

@DanielRosenwasser
Copy link
Member

@typescript-bot pack this

@typescript-bot
Copy link
Collaborator

typescript-bot commented Feb 16, 2024

Heya @DanielRosenwasser, I've started to run the tarball bundle task on this PR at 1148bce. You can monitor the build here.

@typescript-bot
Copy link
Collaborator

typescript-bot commented Feb 16, 2024

Hey @DanielRosenwasser, I've packed this into an installable tgz. You can install it for testing by referencing it in your package.json like so:

{
    "devDependencies": {
        "typescript": "https://typescript.visualstudio.com/cf7ac146-d525-443c-b23c-0d58337efebc/_apis/build/builds/159910/artifacts?artifactName=tgz&fileId=600725B4DA2FE9B98C60B880CE153B4BD0F692165EC94F23DE30C48E7F33B05D02&fileName=/typescript-5.4.0-insiders.20240216.tgz"
    }
}

and then running npm install.


There is also a playground for this build and an npm module you can use via "typescript": "npm:@typescript-deploys/pr-build@5.4.0-pr-57362-11".;

@DanielRosenwasser DanielRosenwasser merged commit feb57c2 into microsoft:main Feb 16, 2024
19 checks passed
@Andarist Andarist deleted the fully-instantiated-constraints-for-infer-type-params branch February 22, 2024 08:27
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.

Wrong type inference, returns the base class type instead of the child class type
5 participants