Skip to content

Generalize the fastpath for comparisons of unions which are correspondences #41903

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

Merged
merged 2 commits into from
Dec 15, 2020

Conversation

weswigham
Copy link
Member

to include unions resulting from the application of intersections on unions.

This expands the fastpath we added in #37749 to handle structures like those produced in #41517 in linear time, bringing the typecheck time of https://github.com/NoPhaseNoKill/ts-slow-compilation-example/tree/main/src down on my machine to ~3s, down from ~30s.

@typescript-bot typescript-bot added Author: Team For Uncommitted Bug PR for untriaged, rejected, closed or missing bug labels Dec 9, 2020
…dences to unions resulting from the application of intersections
@weswigham weswigham force-pushed the generalize-fastpath branch from 08325dd to bcc6aa8 Compare December 9, 2020 19:57
@amcasey
Copy link
Member

amcasey commented Dec 9, 2020

@typescript-bot pack this

@typescript-bot
Copy link
Collaborator

typescript-bot commented Dec 9, 2020

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

@weswigham
Copy link
Member Author

weswigham commented Dec 9, 2020

@typescript-bot perf test this - curious to see if this affects material-ui or CompilerUnions meaningfully (it might, it might not - this is only expanding an existing fast path to more cases, after all).

@typescript-bot
Copy link
Collaborator

typescript-bot commented Dec 9, 2020

Heya @weswigham, I've started to run the perf test suite on this PR at bcc6aa8. You can monitor the build here.

Update: The results are in!

@typescript-bot
Copy link
Collaborator

typescript-bot commented Dec 9, 2020

Hey @amcasey, 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/90815/artifacts?artifactName=tgz&fileId=DE437E052E2A09C925D6311430143CB4F5CACA2D42E63804689460E2B465BC7802&fileName=/typescript-4.2.0-insiders.20201209.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@4.2.0-pr-41903-4".;

@typescript-bot
Copy link
Collaborator

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

Here they are:

Comparison Report - master..41903

Metric master 41903 Delta Best Worst
Angular - node (v10.16.3, x64)
Memory used 344,484k (± 0.02%) 344,492k (± 0.02%) +8k (+ 0.00%) 344,345k 344,612k
Parse Time 1.97s (± 0.45%) 1.97s (± 0.45%) -0.00s (- 0.05%) 1.96s 2.00s
Bind Time 0.83s (± 0.67%) 0.84s (± 0.99%) +0.01s (+ 0.97%) 0.82s 0.86s
Check Time 4.94s (± 0.44%) 4.96s (± 0.66%) +0.01s (+ 0.24%) 4.90s 5.05s
Emit Time 5.32s (± 0.53%) 5.33s (± 0.63%) +0.01s (+ 0.21%) 5.27s 5.42s
Total Time 13.07s (± 0.38%) 13.10s (± 0.49%) +0.03s (+ 0.21%) 12.99s 13.28s
Compiler-Unions - node (v10.16.3, x64)
Memory used 205,368k (± 0.08%) 205,293k (± 0.05%) -75k (- 0.04%) 204,875k 205,402k
Parse Time 0.79s (± 0.78%) 0.79s (± 0.85%) -0.00s (- 0.25%) 0.77s 0.80s
Bind Time 0.50s (± 0.73%) 0.49s (± 1.01%) -0.00s (- 0.20%) 0.48s 0.50s
Check Time 11.92s (± 0.84%) 11.88s (± 0.60%) -0.04s (- 0.34%) 11.73s 12.07s
Emit Time 2.35s (± 0.90%) 2.31s (± 0.80%) -0.03s (- 1.45%) 2.28s 2.37s
Total Time 15.55s (± 0.68%) 15.47s (± 0.45%) -0.08s (- 0.51%) 15.32s 15.65s
Monaco - node (v10.16.3, x64)
Memory used 354,867k (± 0.02%) 354,801k (± 0.03%) -66k (- 0.02%) 354,602k 355,026k
Parse Time 1.60s (± 0.57%) 1.60s (± 0.68%) +0.00s (+ 0.19%) 1.58s 1.62s
Bind Time 0.73s (± 0.82%) 0.73s (± 0.80%) +0.00s (+ 0.14%) 0.72s 0.74s
Check Time 5.11s (± 0.47%) 5.11s (± 0.62%) +0.01s (+ 0.14%) 5.02s 5.17s
Emit Time 2.82s (± 0.59%) 2.79s (± 0.40%) -0.02s (- 0.85%) 2.77s 2.81s
Total Time 10.25s (± 0.26%) 10.24s (± 0.31%) -0.02s (- 0.15%) 10.16s 10.30s
TFS - node (v10.16.3, x64)
Memory used 307,855k (± 0.02%) 307,912k (± 0.03%) +58k (+ 0.02%) 307,687k 308,103k
Parse Time 1.24s (± 0.59%) 1.23s (± 0.36%) -0.01s (- 0.48%) 1.22s 1.24s
Bind Time 0.68s (± 1.14%) 0.68s (± 0.53%) +0.01s (+ 0.74%) 0.68s 0.69s
Check Time 4.58s (± 0.37%) 4.58s (± 0.45%) -0.00s (- 0.04%) 4.54s 4.64s
Emit Time 2.94s (± 1.26%) 2.93s (± 1.16%) -0.01s (- 0.41%) 2.85s 3.02s
Total Time 9.44s (± 0.54%) 9.42s (± 0.31%) -0.01s (- 0.13%) 9.35s 9.48s
material-ui - node (v10.16.3, x64)
Memory used 489,487k (± 0.01%) 489,492k (± 0.01%) +5k (+ 0.00%) 489,387k 489,617k
Parse Time 2.06s (± 0.33%) 2.05s (± 0.44%) -0.00s (- 0.24%) 2.03s 2.07s
Bind Time 0.66s (± 0.55%) 0.65s (± 0.58%) -0.01s (- 1.68%) 0.64s 0.65s
Check Time 13.53s (± 0.78%) 13.55s (± 0.88%) +0.03s (+ 0.18%) 13.34s 13.79s
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) 0.00s ( NaN%) 0.00s 0.00s
Total Time 16.24s (± 0.65%) 16.25s (± 0.72%) +0.01s (+ 0.05%) 16.05s 16.47s
Angular - node (v12.1.0, x64)
Memory used 322,347k (± 0.03%) 322,338k (± 0.02%) -10k (- 0.00%) 322,249k 322,556k
Parse Time 1.96s (± 0.45%) 1.96s (± 0.45%) +0.00s (+ 0.15%) 1.93s 1.97s
Bind Time 0.81s (± 0.58%) 0.81s (± 0.55%) -0.01s (- 0.62%) 0.80s 0.82s
Check Time 4.87s (± 0.82%) 4.85s (± 0.53%) -0.02s (- 0.35%) 4.81s 4.92s
Emit Time 5.46s (± 0.65%) 5.48s (± 0.65%) +0.02s (+ 0.42%) 5.40s 5.56s
Total Time 13.10s (± 0.54%) 13.10s (± 0.47%) +0.00s (+ 0.02%) 12.95s 13.23s
Compiler-Unions - node (v12.1.0, x64)
Memory used 191,522k (± 0.05%) 191,468k (± 0.08%) -55k (- 0.03%) 190,936k 191,650k
Parse Time 0.77s (± 0.62%) 0.77s (± 0.77%) +0.00s (+ 0.13%) 0.76s 0.79s
Bind Time 0.50s (± 1.04%) 0.50s (± 0.75%) -0.00s (- 0.80%) 0.49s 0.50s
Check Time 10.68s (± 0.71%) 10.60s (± 0.56%) -0.08s (- 0.75%) 10.47s 10.76s
Emit Time 2.36s (± 1.29%) 2.36s (± 1.36%) -0.01s (- 0.34%) 2.26s 2.42s
Total Time 14.32s (± 0.57%) 14.23s (± 0.43%) -0.09s (- 0.61%) 14.08s 14.37s
Monaco - node (v12.1.0, x64)
Memory used 337,084k (± 0.02%) 336,983k (± 0.01%) -101k (- 0.03%) 336,920k 337,090k
Parse Time 1.58s (± 0.51%) 1.58s (± 0.57%) -0.00s (- 0.06%) 1.56s 1.60s
Bind Time 0.71s (± 0.52%) 0.70s (± 0.52%) -0.00s (- 0.28%) 0.70s 0.71s
Check Time 4.92s (± 0.56%) 4.89s (± 0.39%) -0.03s (- 0.69%) 4.84s 4.92s
Emit Time 2.86s (± 0.80%) 2.86s (± 0.42%) -0.00s (- 0.10%) 2.83s 2.89s
Total Time 10.07s (± 0.47%) 10.03s (± 0.23%) -0.04s (- 0.41%) 9.98s 10.09s
TFS - node (v12.1.0, x64)
Memory used 292,129k (± 0.01%) 292,103k (± 0.03%) -26k (- 0.01%) 291,930k 292,247k
Parse Time 1.24s (± 0.54%) 1.25s (± 0.93%) +0.00s (+ 0.24%) 1.22s 1.28s
Bind Time 0.65s (± 0.85%) 0.66s (± 0.76%) +0.00s (+ 0.46%) 0.65s 0.67s
Check Time 4.50s (± 0.54%) 4.49s (± 0.43%) -0.01s (- 0.18%) 4.44s 4.53s
Emit Time 2.94s (± 0.48%) 2.95s (± 0.63%) +0.01s (+ 0.31%) 2.90s 3.00s
Total Time 9.34s (± 0.39%) 9.34s (± 0.27%) +0.00s (+ 0.03%) 9.29s 9.40s
material-ui - node (v12.1.0, x64)
Memory used 467,509k (± 0.06%) 467,617k (± 0.01%) +108k (+ 0.02%) 467,478k 467,706k
Parse Time 2.08s (± 0.52%) 2.07s (± 0.50%) -0.01s (- 0.34%) 2.05s 2.10s
Bind Time 0.65s (± 1.26%) 0.64s (± 0.56%) -0.00s (- 0.46%) 0.64s 0.65s
Check Time 12.06s (± 0.71%) 12.00s (± 0.52%) -0.06s (- 0.52%) 11.85s 12.13s
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) 0.00s ( NaN%) 0.00s 0.00s
Total Time 14.78s (± 0.62%) 14.72s (± 0.40%) -0.07s (- 0.45%) 14.59s 14.85s
Angular - node (v8.9.0, x64)
Memory used 347,064k (± 0.02%) 347,083k (± 0.02%) +19k (+ 0.01%) 346,988k 347,251k
Parse Time 2.51s (± 0.22%) 2.52s (± 0.42%) +0.01s (+ 0.48%) 2.50s 2.54s
Bind Time 0.86s (± 0.52%) 0.87s (± 0.79%) +0.00s (+ 0.46%) 0.85s 0.88s
Check Time 5.59s (± 0.79%) 5.59s (± 0.68%) +0.01s (+ 0.13%) 5.50s 5.66s
Emit Time 6.33s (± 1.66%) 6.39s (± 1.15%) +0.07s (+ 1.06%) 6.27s 6.59s
Total Time 15.28s (± 0.83%) 15.38s (± 0.66%) +0.09s (+ 0.60%) 15.16s 15.61s
Compiler-Unions - node (v8.9.0, x64)
Memory used 213,127k (± 0.02%) 213,151k (± 0.03%) +24k (+ 0.01%) 213,002k 213,292k
Parse Time 0.95s (± 0.55%) 0.95s (± 0.70%) -0.00s (- 0.11%) 0.94s 0.97s
Bind Time 0.58s (± 1.11%) 0.58s (± 0.99%) -0.00s (- 0.34%) 0.57s 0.59s
Check Time 14.51s (± 1.66%) 14.57s (± 0.94%) +0.06s (+ 0.39%) 14.28s 14.91s
Emit Time 2.73s (± 2.10%) 2.71s (± 2.82%) -0.02s (- 0.55%) 2.58s 2.86s
Total Time 18.78s (± 1.39%) 18.81s (± 1.05%) +0.03s (+ 0.18%) 18.41s 19.31s
Monaco - node (v8.9.0, x64)
Memory used 358,735k (± 0.01%) 358,764k (± 0.02%) +29k (+ 0.01%) 358,615k 358,962k
Parse Time 1.92s (± 0.39%) 1.93s (± 0.52%) +0.00s (+ 0.10%) 1.90s 1.94s
Bind Time 0.91s (± 0.44%) 0.91s (± 0.88%) -0.00s (- 0.11%) 0.89s 0.92s
Check Time 5.63s (± 0.45%) 5.64s (± 0.32%) +0.01s (+ 0.23%) 5.60s 5.69s
Emit Time 3.40s (± 0.39%) 3.43s (± 0.27%) +0.03s (+ 0.88%) 3.41s 3.45s
Total Time 11.86s (± 0.27%) 11.91s (± 0.18%) +0.04s (+ 0.38%) 11.86s 11.95s
TFS - node (v8.9.0, x64)
Memory used 310,533k (± 0.02%) 310,483k (± 0.01%) -50k (- 0.02%) 310,404k 310,579k
Parse Time 1.57s (± 0.51%) 1.56s (± 0.48%) -0.00s (- 0.26%) 1.55s 1.58s
Bind Time 0.68s (± 0.53%) 0.68s (± 0.50%) -0.00s (- 0.15%) 0.68s 0.69s
Check Time 5.34s (± 0.58%) 5.32s (± 0.51%) -0.02s (- 0.34%) 5.29s 5.42s
Emit Time 2.99s (± 0.85%) 2.95s (± 0.93%) -0.04s (- 1.17%) 2.88s 3.01s
Total Time 10.58s (± 0.47%) 10.52s (± 0.42%) -0.06s (- 0.54%) 10.43s 10.61s
material-ui - node (v8.9.0, x64)
Memory used 496,663k (± 0.02%) 496,656k (± 0.01%) -7k (- 0.00%) 496,564k 496,770k
Parse Time 2.49s (± 0.55%) 2.49s (± 0.12%) 0.00s ( 0.00%) 2.49s 2.50s
Bind Time 0.80s (± 1.03%) 0.80s (± 0.94%) -0.00s (- 0.00%) 0.79s 0.82s
Check Time 18.10s (± 0.67%) 18.05s (± 0.62%) -0.05s (- 0.27%) 17.76s 18.29s
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) 0.00s ( NaN%) 0.00s 0.00s
Total Time 21.40s (± 0.58%) 21.35s (± 0.55%) -0.05s (- 0.23%) 21.04s 21.59s
Angular - node (v8.9.0, x86)
Memory used 199,099k (± 0.03%) 199,092k (± 0.02%) -7k (- 0.00%) 198,995k 199,185k
Parse Time 2.43s (± 0.56%) 2.43s (± 0.39%) +0.00s (+ 0.08%) 2.42s 2.46s
Bind Time 1.01s (± 1.05%) 1.01s (± 0.99%) -0.00s (- 0.20%) 0.99s 1.03s
Check Time 5.05s (± 0.67%) 5.03s (± 0.60%) -0.02s (- 0.36%) 4.97s 5.10s
Emit Time 6.07s (± 1.37%) 6.07s (± 1.23%) -0.00s (- 0.08%) 5.92s 6.25s
Total Time 14.56s (± 0.79%) 14.54s (± 0.50%) -0.02s (- 0.14%) 14.38s 14.73s
Compiler-Unions - node (v8.9.0, x86)
Memory used 128,100k (± 0.03%) 128,090k (± 0.04%) -10k (- 0.01%) 127,979k 128,177k
Parse Time 0.96s (± 0.68%) 0.96s (± 0.85%) +0.00s (+ 0.21%) 0.95s 0.98s
Bind Time 0.50s (± 1.46%) 0.50s (± 1.30%) +0.00s (+ 0.00%) 0.49s 0.51s
Check Time 13.69s (± 0.62%) 13.68s (± 0.46%) -0.01s (- 0.07%) 13.57s 13.82s
Emit Time 2.63s (± 0.85%) 2.64s (± 0.71%) +0.01s (+ 0.30%) 2.60s 2.67s
Total Time 17.77s (± 0.45%) 17.77s (± 0.42%) 0.00s ( 0.00%) 17.63s 17.96s
Monaco - node (v8.9.0, x86)
Memory used 203,211k (± 0.02%) 203,215k (± 0.02%) +4k (+ 0.00%) 203,107k 203,295k
Parse Time 1.97s (± 0.93%) 1.98s (± 0.56%) +0.01s (+ 0.51%) 1.96s 2.00s
Bind Time 0.72s (± 1.01%) 0.72s (± 0.81%) -0.00s (- 0.14%) 0.70s 0.73s
Check Time 5.75s (± 1.35%) 5.79s (± 1.33%) +0.05s (+ 0.80%) 5.54s 5.98s
Emit Time 2.81s (± 3.15%) 2.77s (± 3.40%) -0.04s (- 1.60%) 2.69s 3.14s
Total Time 11.24s (± 0.41%) 11.26s (± 0.53%) +0.01s (+ 0.12%) 11.18s 11.43s
TFS - node (v8.9.0, x86)
Memory used 177,633k (± 0.02%) 177,629k (± 0.02%) -4k (- 0.00%) 177,521k 177,727k
Parse Time 1.61s (± 1.04%) 1.62s (± 0.82%) +0.01s (+ 0.74%) 1.60s 1.66s
Bind Time 0.65s (± 0.46%) 0.65s (± 1.04%) +0.00s (+ 0.31%) 0.64s 0.67s
Check Time 4.86s (± 0.77%) 4.86s (± 0.74%) -0.00s (- 0.02%) 4.79s 4.95s
Emit Time 2.82s (± 0.90%) 2.84s (± 0.87%) +0.02s (+ 0.64%) 2.81s 2.91s
Total Time 9.95s (± 0.38%) 9.98s (± 0.35%) +0.03s (+ 0.34%) 9.91s 10.04s
material-ui - node (v8.9.0, x86)
Memory used 279,662k (± 0.02%) 279,676k (± 0.02%) +14k (+ 0.01%) 279,586k 279,768k
Parse Time 2.55s (± 0.86%) 2.56s (± 0.83%) +0.01s (+ 0.20%) 2.52s 2.62s
Bind Time 0.71s (± 4.10%) 0.72s (± 4.20%) +0.01s (+ 1.13%) 0.69s 0.83s
Check Time 16.44s (± 0.91%) 16.56s (± 0.69%) +0.12s (+ 0.72%) 16.32s 16.85s
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) 0.00s ( NaN%) 0.00s 0.00s
Total Time 19.70s (± 0.88%) 19.83s (± 0.60%) +0.13s (+ 0.68%) 19.53s 20.10s
System
Machine Namets-ci-ubuntu
Platformlinux 4.4.0-197-generic
Architecturex64
Available Memory16 GB
Available Memory11 GB
CPUs4 × Intel(R) Core(TM) i7-4770 CPU @ 3.40GHz
Hosts
  • node (v10.16.3, x64)
  • node (v12.1.0, x64)
  • node (v8.9.0, x64)
  • node (v8.9.0, x86)
Scenarios
  • Angular - node (v10.16.3, x64)
  • Angular - node (v12.1.0, x64)
  • Angular - node (v8.9.0, x64)
  • Angular - node (v8.9.0, x86)
  • Compiler-Unions - node (v10.16.3, x64)
  • Compiler-Unions - node (v12.1.0, x64)
  • Compiler-Unions - node (v8.9.0, x64)
  • Compiler-Unions - node (v8.9.0, x86)
  • Monaco - node (v10.16.3, x64)
  • Monaco - node (v12.1.0, x64)
  • Monaco - node (v8.9.0, x64)
  • Monaco - node (v8.9.0, x86)
  • TFS - node (v10.16.3, x64)
  • TFS - node (v12.1.0, x64)
  • TFS - node (v8.9.0, x64)
  • TFS - node (v8.9.0, x86)
  • material-ui - node (v10.16.3, x64)
  • material-ui - node (v12.1.0, x64)
  • material-ui - node (v8.9.0, x64)
  • material-ui - node (v8.9.0, x86)
Benchmark Name Iterations
Current 41903 10
Baseline master 10

@amcasey
Copy link
Member

amcasey commented Dec 9, 2020

I'm having trouble reasoning about the case where the target type is bigger. Is that interesting too?

for (let i = 0; i < sourceTypes.length; i++) {
const sourceType = sourceTypes[i];
if (target.flags & TypeFlags.Union && (target as UnionType).types.length === sourceTypes.length) {
if (undefinedStrippedTarget.flags & TypeFlags.Union && sourceTypes.length >= (undefinedStrippedTarget as UnionType).types.length && sourceTypes.length % (undefinedStrippedTarget as UnionType).types.length === 0) {
Copy link
Member

Choose a reason for hiding this comment

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

We seem to access (undefinedStrippedTarget as UnionType).types.length quite a few times. Would it be worthwhile to extract it out of the loop, since it won't change?

Copy link
Member Author

Choose a reason for hiding this comment

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

Ehh, it's a little awkward because we can only get it after the Union flag check, which is done internally to the loop.

const related = isRelatedTo(sourceType, (target as UnionType).types[i], /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState);
// such unions will have identical lengths, and their corresponding elements will match up. Another common scenario is where a large
// union has a union of objects intersected with it. In such cases, if the input was, eg `("a" | "b" | "c") & (string | boolean | {} | {whatever})`,
// the result will have the structure `"a" | "b" | "c" | "a" & {} | "b" & {} | "c" & {} | "a" & {whatever} | "b" & {whatever} | "c" & {whatever}`
Copy link
Member

Choose a reason for hiding this comment

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

Is this order guaranteed somehow? If not, would we have someway of knowing that it changed, breaking this optimization?

Copy link
Member Author

Choose a reason for hiding this comment

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

Kind-of. It's not guaranteed, just very often true. Often enough to be a useful heuristic. Unions are sorted by type IDs, type IDs are assigned on type construction, type are constructed in a top-down/left-to-right/as-they-appear kinda way when normalizing or mapping (mostly as an artifact of our mostly lazy compiler design). A notable thing that can easily break this ordering heuristic is code which pulls one of the type out of the union and makes it in advance, for example:

type A = {a};
type B = {b};
type FooB = "foo" & B;
type Union = ("foo" | "bar") & (A | B);

The presence of the FooB type changes the order in the Union type. Not much to be done when that happens, except hope it doesn't shift around too much. (Since partial correspondences still benefit from this check, just not as much) That's one reason why we still fall back to the exhaustive check if the corresponding element fails to match.

Copy link
Member Author

Choose a reason for hiding this comment

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

If not, would we have someway of knowing that it changed, breaking this optimization?

That test that I commented on in the other PR would time out, for one. :V

@@ -17258,14 +17258,29 @@ namespace ts {
return Ternary.False;
}

function getUndefinedStrippedTargetIfNeeded(source: Type, target: Type) {
// As a builtin type, `undefined` is a very low type ID - making it almsot always first, making this a very fast check to see
Copy link
Member

Choose a reason for hiding this comment

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

almost

Copy link
Member

Choose a reason for hiding this comment

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

What types have lower type IDs? This seems potentially fragile.

Copy link
Member Author

Choose a reason for hiding this comment

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

Only the any-likes are manufactured before undefined (yes, this is arbitrary and fragile, but it turns out, also useful), and they can't exist in a union: so undefined will actually always be the first element, if present.

@weswigham weswigham merged commit b9f372e into microsoft:master Dec 15, 2020
@weswigham weswigham deleted the generalize-fastpath branch December 15, 2020 21:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Author: Team For Uncommitted Bug PR for untriaged, rejected, closed or missing bug
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants