Skip to content

Instantiate earlier inferred constraints in conditional types - #57362

Merged
Daniel Rosenwasser (DanielRosenwasser) merged 1 commit into
microsoft:mainfrom
Andarist:fully-instantiated-constraints-for-infer-type-params
Feb 16, 2024
Merged

Instantiate earlier inferred constraints in conditional types#57362
Daniel Rosenwasser (DanielRosenwasser) merged 1 commit into
microsoft:mainfrom
Andarist:fully-instantiated-constraints-for-infer-type-params

Conversation

@Andarist

Copy link
Copy Markdown
Contributor

fixes#57286 (comment)

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

@jakebailey

Copy link
Copy Markdown
Member

@typescript-bot

TypeScript Bot (typescript-bot) commented Feb 9, 2024

Copy link
Copy Markdown
Contributor

Heya Jake Bailey (@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

TypeScript Bot (typescript-bot) commented Feb 9, 2024

Copy link
Copy Markdown
Contributor

Heya Jake Bailey (@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

TypeScript Bot (typescript-bot) commented Feb 9, 2024

Copy link
Copy Markdown
Contributor

Heya Jake Bailey (@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

TypeScript Bot (typescript-bot) commented Feb 9, 2024

Copy link
Copy Markdown
Contributor

Heya Jake Bailey (@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
Copy Markdown
ContributorAuthor

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
Copy Markdown
Contributor

Jake Bailey (@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
Copy Markdown
Contributor

Jake Bailey (@jakebailey)
The results of the perf run you requested are in!

Here they are:

tsc

Comparison Report - baseline..pr
MetricbaselineprDeltaBestWorstp-value
Angular - node (v18.15.0, x64)
Memory used295,672k (± 0.01%)295,669k (± 0.01%)~295,637k295,721kp=0.810 n=6
Parse Time2.66s (± 0.24%)2.65s (± 0.55%)~2.63s2.67sp=0.345 n=6
Bind Time0.82s (± 0.66%)0.83s (± 1.92%)~0.81s0.85sp=0.498 n=6
Check Time8.21s (± 0.23%)8.20s (± 0.23%)~8.18s8.23sp=0.807 n=6
Emit Time7.10s (± 0.24%)7.09s (± 0.29%)~7.06s7.11sp=0.806 n=6
Total Time18.79s (± 0.17%)18.78s (± 0.13%)~18.74s18.81sp=0.333 n=6
Compiler-Unions - node (v18.15.0, x64)
Memory used193,500k (± 1.55%)193,897k (± 1.47%)~191,464k197,360kp=1.000 n=6
Parse Time1.35s (± 0.47%)1.36s (± 0.55%)~1.35s1.37sp=0.081 n=6
Bind Time0.72s (± 0.00%)0.72s (± 0.00%)~0.72s0.72sp=1.000 n=6
Check Time9.37s (± 0.55%)9.37s (± 0.24%)~9.34s9.40sp=0.872 n=6
Emit Time2.62s (± 0.66%)2.61s (± 0.59%)~2.59s2.63sp=0.461 n=6
Total Time14.06s (± 0.29%)14.06s (± 0.12%)~14.03s14.08sp=0.808 n=6
Monaco - node (v18.15.0, x64)
Memory used347,464k (± 0.00%)347,467k (± 0.01%)~347,436k347,488kp=0.574 n=6
Parse Time2.48s (± 0.72%)2.47s (± 0.33%)~2.46s2.48sp=0.324 n=6
Bind Time0.93s (± 0.56%)0.92s (± 0.56%)~0.92s0.93sp=0.311 n=6
Check Time6.95s (± 0.37%)6.94s (± 0.30%)~6.92s6.98sp=0.418 n=6
Emit Time4.06s (± 0.61%)4.07s (± 0.55%)~4.03s4.09sp=0.684 n=6
Total Time14.42s (± 0.16%)14.40s (± 0.24%)~14.34s14.44sp=0.462 n=6
TFS - node (v18.15.0, x64)
Memory used302,857k (± 0.00%)302,849k (± 0.00%)~302,824k302,861kp=0.422 n=6
Parse Time2.02s (± 0.73%)2.02s (± 0.52%)~2.01s2.04sp=0.805 n=6
Bind Time1.00s (± 0.81%)1.00s (± 0.98%)~0.99s1.02sp=0.673 n=6
Check Time6.34s (± 0.44%)6.34s (± 0.41%)~6.30s6.37sp=0.936 n=6
Emit Time3.60s (± 0.38%)3.60s (± 0.42%)~3.59s3.63sp=1.000 n=6
Total Time12.96s (± 0.24%)12.97s (± 0.30%)~12.91s13.00sp=0.935 n=6
material-ui - node (v18.15.0, x64)
Memory used511,369k (± 0.00%)511,378k (± 0.01%)~511,346k511,421kp=0.689 n=6
Parse Time2.64s (± 0.66%)2.65s (± 0.62%)~2.63s2.67sp=0.281 n=6
Bind Time0.99s (± 0.55%)1.00s (± 0.82%)~0.99s1.01sp=0.859 n=6
Check Time17.25s (± 0.33%)17.34s (± 0.43%)~17.25s17.43sp=0.054 n=6
Emit Time0.00s (± 0.00%)0.00s (± 0.00%)~0.00s0.00sp=1.000 n=6
Total Time20.88s (± 0.29%)20.99s (± 0.41%)+0.11s (+ 0.53%)20.87s21.09sp=0.045 n=6
mui-docs - node (v18.15.0, x64)
Memory used2,269,547k (± 0.00%)2,269,595k (± 0.00%)+48k (+ 0.00%)2,269,565k2,269,627kp=0.010 n=6
Parse Time11.86s (± 0.61%)11.92s (± 0.73%)~11.86s12.09sp=0.092 n=6
Bind Time2.64s (± 0.32%)2.65s (± 0.32%)~2.63s2.65sp=0.084 n=6
Check Time101.19s (± 0.63%)101.04s (± 0.58%)~100.33s101.66sp=0.689 n=6
Emit Time0.32s (± 1.28%)0.32s (± 1.28%)~0.31s0.32sp=1.000 n=6
Total Time116.01s (± 0.55%)115.93s (± 0.45%)~115.26s116.53sp=0.936 n=6
self-build-src - node (v18.15.0, x64)
Memory used2,414,079k (± 0.01%)2,413,593k (± 0.01%)-486k (- 0.02%)2,413,304k2,413,888kp=0.013 n=6
Parse Time4.94s (± 1.01%)4.91s (± 0.30%)~4.89s4.92sp=0.422 n=6
Bind Time1.88s (± 1.00%)1.86s (± 0.65%)~1.84s1.87sp=0.104 n=6
Check Time33.39s (± 0.22%)33.32s (± 0.25%)~33.16s33.38sp=0.229 n=6
Emit Time2.70s (± 1.60%)2.66s (± 0.63%)-0.04s (- 1.42%)2.65s2.69sp=0.044 n=6
Total Time42.92s (± 0.20%)42.77s (± 0.20%)-0.15s (- 0.35%)42.60s42.81sp=0.008 n=6
self-compiler - node (v18.15.0, x64)
Memory used418,763k (± 0.01%)418,795k (± 0.01%)~418,708k418,896kp=0.230 n=6
Parse Time2.79s (± 2.62%)2.82s (± 2.99%)~2.66s2.89sp=0.166 n=6
Bind Time1.10s (± 4.91%)1.11s (± 5.54%)~1.08s1.23sp=0.599 n=6
Check Time15.10s (± 0.20%)15.11s (± 0.24%)~15.05s15.16sp=0.933 n=6
Emit Time1.14s (± 0.90%)1.13s (± 0.91%)~1.12s1.15sp=0.134 n=6
Total Time20.14s (± 0.16%)20.17s (± 0.13%)~20.13s20.20sp=0.107 n=6
vscode - node (v18.15.0, x64)
Memory used2,828,957k (± 0.00%)2,828,985k (± 0.00%)~2,828,940k2,829,025kp=0.336 n=6
Parse Time10.74s (± 0.54%)10.71s (± 0.39%)~10.67s10.77sp=0.421 n=6
Bind Time3.42s (± 0.16%)3.43s (± 0.44%)~3.41s3.45sp=0.865 n=6
Check Time59.83s (± 0.49%)60.07s (± 0.45%)~59.74s60.47sp=0.128 n=6
Emit Time16.24s (± 0.21%)16.18s (± 0.31%)~16.11s16.24sp=0.076 n=6
Total Time90.23s (± 0.35%)90.39s (± 0.30%)~90.04s90.79sp=0.298 n=6
webpack - node (v18.15.0, x64)
Memory used393,995k (± 0.01%)393,973k (± 0.01%)~393,923k394,044kp=0.378 n=6
Parse Time3.10s (± 0.56%)3.11s (± 0.57%)~3.08s3.13sp=0.255 n=6
Bind Time1.38s (± 1.25%)1.38s (± 1.06%)~1.37s1.40sp=0.933 n=6
Check Time14.06s (± 0.16%)14.03s (± 0.14%)~14.00s14.05sp=0.063 n=6
Emit Time0.00s (± 0.00%)0.00s (± 0.00%)~0.00s0.00sp=1.000 n=6
Total Time18.54s (± 0.17%)18.52s (± 0.19%)~18.46s18.56sp=0.572 n=6
xstate - node (v18.15.0, x64)
Memory used513,391k (± 0.01%)513,417k (± 0.01%)~513,342k513,480kp=0.297 n=6
Parse Time3.27s (± 0.19%)3.28s (± 0.25%)~3.27s3.29sp=0.177 n=6
Bind Time1.54s (± 0.41%)1.54s (± 0.35%)~1.54s1.55sp=0.201 n=6
Check Time2.86s (± 0.94%)2.85s (± 0.62%)~2.84s2.89sp=0.288 n=6
Emit Time0.08s (± 5.21%)0.08s (± 4.99%)~0.08s0.09sp=0.218 n=6
Total Time7.76s (± 0.34%)7.76s (± 0.29%)~7.74s7.80sp=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)
BenchmarkNameIterations
Currentpr6
Baselinebaseline6

Developer Information:

Download Benchmarks

@typescript-bot

Copy link
Copy Markdown
Contributor

Hey Jake Bailey (@jakebailey), the results of running the DT tests are ready.
Everything looks the same!
You can check the log here.

@typescript-bot

Copy link
Copy Markdown
Contributor

Jake Bailey (@jakebailey) Here are the results of running the top-repos suite comparing main and refs/pull/57362/merge:

Everything looks good!

Copy link
Copy Markdown
Member

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
Copy Markdown
Member

TypeScript Bot (@typescript-bot) pack this

@typescript-bot

TypeScript Bot (typescript-bot) commented Feb 16, 2024

Copy link
Copy Markdown
Contributor

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

@typescript-bot

TypeScript Bot (typescript-bot) commented Feb 16, 2024

Copy link
Copy Markdown
Contributor

Hey Daniel Rosenwasser (@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".;

Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

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

@Andarist@jakebailey@typescript-bot@DanielRosenwasser@weswigham