Skip to content

Prefer covariant inferences with deeper type argument nesting#4389

Open
ahejlsberg wants to merge 5 commits into
mainfrom
fix-1789
Open

Prefer covariant inferences with deeper type argument nesting#4389
ahejlsberg wants to merge 5 commits into
mainfrom
fix-1789

Conversation

@ahejlsberg

Copy link
Copy Markdown
Member

With this PR we give preference to covariant inferences made from type arguments with deeper nesting. Intuitively, a successful inference from a type argument with deeper nesting is of higher quality because we've stripped away more layers of type instantiations that otherwise might skew the results. Specifically, when inferring from Array<string> | Array<Array<string>> to Array<T> | Array<Array<T>>, the inference of string we make from relating Array<Array<string>> to Array<Array<T>> is of higher quality than the inference of Array<string> we make relating Array<Array<string>> to Array<T>.

The PR only tracks type argument inference depths for covariant inferences. We could potentially also track for contravariant inferences, though they're rare enough that it doesn't seem worth it.

Fixes #1789.

@ahejlsberg

Copy link
Copy Markdown
Member Author

This PR supersedes #3391, which isn't quite the right way to solve the issue.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR adjusts the checker’s generic type inference to prefer covariant inference candidates derived from more deeply-nested type arguments, addressing #1789’s failure to infer T correctly for unions like T[] | T[][].

Changes:

  • Track type-argument nesting depth during inference and use it to prioritize covariant inference candidates.
  • Add a new compiler regression test (nestedGenericTypeInference.ts) covering the reported array-depth union scenario (and a few related nesting shapes).
  • Update compiler baselines and submodule baselines impacted by the inference behavior change.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
internal/checker/inference.go Tracks inference depth during inferFromTypeArguments and uses it to order/replace covariant inference candidates.
internal/checker/checker.go Extends InferenceInfo to record candidate depths alongside covariant candidates.
testdata/tests/cases/compiler/nestedGenericTypeInference.ts New regression test for nested/union generic inference depth behavior (Fixes #1789).
testdata/baselines/reference/compiler/nestedGenericTypeInference.types New types baseline for the added regression test.
testdata/baselines/reference/compiler/nestedGenericTypeInference.symbols New symbols baseline for the added regression test.
testdata/baselines/reference/submodule/conformance/assignmentCompatWithGenericCallSignatures2.errors.txt Updated submodule baseline reflecting changed diagnostics.
testdata/baselines/reference/submodule/conformance/assignmentCompatWithGenericCallSignatures2.errors.txt.diff Newly-added submodule diff capturing a new divergence vs upstream diagnostics.

Comment on lines +4 to +8
assignmentCompatWithGenericCallSignatures2.ts(15,1): error TS2322: Type 'B' is not assignable to type 'A'.
- Types of parameters 'y' and 'y' are incompatible.
- Type 'T[]' is not assignable to type 'T'.
- 'T' could be instantiated with an arbitrary type which could be unrelated to 'T[]'.
+ Types of parameters 'x' and 'x' are incompatible.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This is intended.

@ahejlsberg

Copy link
Copy Markdown
Member Author

@typescript-bot test it

@typescript-automation

typescript-automation Bot commented Jun 22, 2026

Copy link
Copy Markdown

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

Command Status Results
test top400 ❌ Error: Error: Could not queue the build because there were validation errors or warnings.
perf test this faster ✅ Started 👀 Results

@typescript-automation

Copy link
Copy Markdown

@ahejlsberg
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 - native
Errors 4 4 ~ ~ ~ p=1.000 n=6
Symbols 81,777 (± 0.04%) 81,785 (± 0.03%) ~ 81,739 81,808 p=0.810 n=6
Types 98,821 98,821 ~ ~ ~ p=1.000 n=6
Memory Used 179,465k (± 0.40%) 180,065k (± 0.24%) ~ 179,594k 180,864k p=0.066 n=6
Memory Allocs 2,546,403 (± 0.02%) 2,547,392 (± 0.01%) +988 (+ 0.04%) 2,547,263 2,547,746 p=0.005 n=6
Config Time 0.000s (±244.70%) 0.000s ~ ~ ~ p=0.405 n=6
Parse Time 0.064s (± 6.74%) 0.060s (± 5.79%) ~ 0.056s 0.063s p=0.373 n=6
Bind Time 0.016s (±23.69%) 0.017s (± 5.83%) ~ 0.016s 0.018s p=0.373 n=6
Check Time 0s 0s ~ ~ ~ p=1.000 n=6
Emit Time 0.881s (± 1.41%) 0.873s (± 1.09%) ~ 0.865s 0.889s p=0.298 n=6
Total Time 0.963s (± 1.64%) 0.951s (± 0.84%) ~ 0.943s 0.963s p=0.261 n=6
angular-1 - native
Errors 3 3 ~ ~ ~ p=1.000 n=6
Symbols 876,420 (± 0.08%) 876,937 (± 0.11%) ~ 875,693 878,438 p=0.298 n=6
Types 263,748 (± 0.00%) 263,749 (± 0.00%) ~ 263,748 263,751 p=0.293 n=6
Memory Used 830,476k (± 0.07%) 831,163k (± 0.11%) ~ 830,451k 832,893k p=0.093 n=6
Memory Allocs 12,599,689 (± 0.21%) 12,659,747 (± 0.21%) +60,058 (+ 0.48%) 12,641,420 12,709,946 p=0.031 n=6
Config Time 0.017s (± 2.38%) 0.017s (± 2.42%) ~ 0.016s 0.017s p=0.218 n=6
Parse Time 0.241s (± 5.34%) 0.246s (± 4.20%) ~ 0.231s 0.257s p=0.423 n=6
Bind Time 0.042s (±19.93%) 0.053s (±33.51%) ~ 0.039s 0.084s p=0.173 n=6
Check Time 0s 0s ~ ~ ~ p=1.000 n=6
Emit Time 1.893s (± 1.58%) 1.918s (± 1.74%) ~ 1.883s 1.960s p=0.199 n=6
Total Time 2.205s (± 1.17%) 2.247s (± 1.00%) +0.041s (+ 1.88%) 2.223s 2.280s p=0.031 n=6
mui-docs - native
Errors 11,280 (± 0.03%) 11,280 (± 0.03%) ~ 11,275 11,283 p=0.739 n=6
Symbols 4,214,832 4,214,927 +95 (+ 0.00%) ~ ~ p=0.001 n=6
Types 1,534,279 1,534,296 +17 (+ 0.00%) ~ ~ p=0.001 n=6
Memory Used 4,968,298k (± 0.08%) 4,968,179k (± 0.07%) ~ 4,963,382k 4,971,966k p=1.000 n=6
Memory Allocs 80,429,528 (±17.61%) 85,567,859 (±24.40%) ~ 65,956,612 123,326,049 p=1.000 n=6
Config Time 0.016s (± 2.52%) 0.017s (± 6.19%) ~ 0.016s 0.018s p=0.461 n=6
Parse Time 1.015s (±25.14%) 1.100s (±28.76%) ~ 0.807s 1.674s p=0.689 n=6
Bind Time 0.002s 0.002s ~ ~ ~ p=1.000 n=6
Check Time 16.941s (± 0.68%) 17.032s (± 0.48%) ~ 16.913s 17.129s p=0.149 n=6
Emit Time 0.451s (± 4.63%) 0.438s (± 3.65%) ~ 0.429s 0.470s p=0.226 n=6
Total Time 19.143s (± 1.32%) 19.260s (± 1.27%) ~ 18.976s 19.603s p=0.471 n=6
self-build-src - native
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 1,394,138 1,394,269 +131 (+ 0.01%) ~ ~ p=0.001 n=6
Types 442,153 442,235 +82 (+ 0.02%) ~ ~ p=0.001 n=6
Memory Used 1,647,254k (± 0.32%) 1,650,210k (± 0.24%) ~ 1,644,809k 1,655,923k p=0.378 n=6
Memory Allocs 97,800,803 (± 0.05%) 98,390,922 (± 0.06%) +590,120 (+ 0.60%) 98,316,443 98,435,255 p=0.005 n=6
Config Time 0.017s (±44.91%) 0.014s (±43.56%) ~ 0.006s 0.023s p=0.521 n=6
Parse Time 0.277s (± 6.02%) 0.270s (± 2.83%) ~ 0.260s 0.281s p=0.423 n=6
Bind Time 0.000s 0.000s (±244.70%) ~ 0.000s 0.001s p=0.405 n=6
Check Time 2.340s (± 0.31%) 2.318s (± 0.59%) -0.022s (- 0.95%) 2.302s 2.336s p=0.013 n=6
Emit Time 0.295s (± 4.19%) 0.287s (± 2.38%) ~ 0.274s 0.291s p=0.418 n=6
Total Time 30.671s (± 0.67%) 30.235s (± 0.63%) -0.435s (- 1.42%) 29.989s 30.501s p=0.008 n=6
self-compiler - native
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 337,634 337,637 +3 (+ 0.00%) ~ ~ p=0.001 n=6
Types 199,520 199,520 ~ ~ ~ p=1.000 n=6
Memory Used 332,256k (± 0.02%) 332,531k (± 0.03%) +274k (+ 0.08%) 332,346k 332,648k p=0.008 n=6
Memory Allocs 4,724,898 (± 0.02%) 4,761,373 (± 0.02%) +36,475 (+ 0.77%) 4,760,590 4,762,650 p=0.005 n=6
Config Time 0.001s 0.001s ~ ~ ~ p=1.000 n=6
Parse Time 0.130s (± 6.55%) 0.127s (± 2.40%) ~ 0.123s 0.131s p=1.000 n=6
Bind Time 0.000s 0.000s ~ ~ ~ p=1.000 n=6
Check Time 1.385s (± 0.79%) 1.375s (± 0.55%) ~ 1.365s 1.384s p=0.199 n=6
Emit Time 0.124s (± 4.32%) 0.127s (± 4.78%) ~ 0.121s 0.137s p=0.518 n=6
Total Time 1.694s (± 0.97%) 1.685s (± 0.72%) ~ 1.665s 1.699s p=0.471 n=6
ts-pre-modules - native
Errors 3 3 ~ ~ ~ p=1.000 n=6
Symbols 97,488 97,488 ~ ~ ~ p=1.000 n=6
Types 356 356 ~ ~ ~ p=1.000 n=6
Memory Used 133,704k (± 0.02%) 133,730k (± 0.02%) ~ 133,709k 133,768k p=0.093 n=6
Memory Allocs 183,045 (± 0.19%) 182,919 (± 0.17%) ~ 182,509 183,381 p=0.575 n=6
Config Time 0.001s 0.001s ~ ~ ~ p=1.000 n=6
Parse Time 0.115s (± 3.06%) 0.114s (± 4.30%) ~ 0.109s 0.121s p=0.748 n=6
Bind Time 0.037s (±13.71%) 0.042s (± 7.53%) ~ 0.038s 0.047s p=0.091 n=6
Check Time 0s 0s ~ ~ ~ p=1.000 n=6
Emit Time 0.000s 0.000s ~ ~ ~ p=1.000 n=6
Total Time 0.155s (± 3.97%) 0.160s (± 3.86%) ~ 0.153s 0.166s p=0.297 n=6
vscode - native
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 6,654,188 6,654,254 +66 (+ 0.00%) ~ ~ p=0.001 n=6
Types 2,360,033 2,360,046 +13 (+ 0.00%) ~ ~ p=0.001 n=6
Memory Used 4,554,074k (± 0.01%) 4,555,355k (± 0.02%) +1,281k (+ 0.03%) 4,554,008k 4,556,074k p=0.020 n=6
Memory Allocs 32,009,035 (± 0.01%) 32,319,226 (± 0.07%) +310,192 (+ 0.97%) 32,292,357 32,361,417 p=0.005 n=6
Config Time 0.074s (± 9.96%) 0.073s (± 9.69%) ~ 0.065s 0.083s p=0.689 n=6
Parse Time 0.898s (± 5.30%) 0.854s (± 2.58%) 🟩-0.044s (- 4.92%) 0.824s 0.878s p=0.045 n=6
Bind Time 0.150s (±17.92%) 0.173s (±39.62%) ~ 0.128s 0.294s p=1.000 n=6
Check Time 9.046s (± 0.89%) 9.129s (± 1.01%) ~ 9.021s 9.241s p=0.093 n=6
Emit Time 2.328s (±10.67%) 2.291s (± 9.88%) ~ 2.077s 2.543s p=0.810 n=6
Total Time 12.517s (± 1.38%) 12.538s (± 0.89%) ~ 12.421s 12.722s p=0.936 n=6
webpack - native
Errors 2 2 ~ ~ ~ p=1.000 n=6
Symbols 182,773 182,773 ~ ~ ~ p=1.000 n=6
Types 340 340 ~ ~ ~ p=1.000 n=6
Memory Used 221,532k (± 0.18%) 221,608k (± 0.08%) ~ 221,364k 221,771k p=0.471 n=6
Memory Allocs 1,065,903 (± 0.36%) 1,066,835 (± 0.32%) ~ 1,063,301 1,072,316 p=0.810 n=6
Config Time 0.011s (±14.10%) 0.012s (±21.10%) ~ 0.008s 0.014s p=0.568 n=6
Parse Time 0.151s (± 5.19%) 0.149s (± 5.94%) ~ 0.136s 0.160s p=0.872 n=6
Bind Time 0s 0s ~ ~ ~ p=1.000 n=6
Check Time 0s 0s ~ ~ ~ p=1.000 n=6
Emit Time 0.041s (±24.00%) 0.039s (±17.40%) ~ 0.034s 0.052s p=0.872 n=6
Total Time 0.203s (± 5.18%) 0.200s (± 3.76%) ~ 0.189s 0.206s p=0.521 n=6
xstate-main - native
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 1,065,023 1,065,023 ~ ~ ~ p=1.000 n=6
Types 389,185 389,185 ~ ~ ~ p=1.000 n=6
Memory Used 643,083k (± 0.02%) 643,769k (± 0.02%) +686k (+ 0.11%) 643,568k 643,905k p=0.005 n=6
Memory Allocs 5,066,643 (± 0.25%) 5,103,388 (± 0.15%) +36,745 (+ 0.73%) 5,096,974 5,115,847 p=0.005 n=6
Config Time 0.005s 0.005s (±11.05%) ~ 0.004s 0.005s p=0.174 n=6
Parse Time 0.135s (± 4.17%) 0.133s (± 4.09%) ~ 0.127s 0.139s p=0.418 n=6
Bind Time 0.032s (±18.79%) 0.034s (±30.11%) ~ 0.023s 0.046s p=0.810 n=6
Check Time 1.299s (± 0.72%) 1.303s (± 0.58%) ~ 1.297s 1.316s p=0.422 n=6
Emit Time 0.001s 0.001s ~ ~ ~ p=1.000 n=6
Total Time 1.477s (± 0.77%) 1.481s (± 0.54%) ~ 1.467s 1.487s p=0.520 n=6
System info unknown
Hosts
  • native
Scenarios
  • Compiler-Unions - native
  • angular-1 - native
  • mui-docs - native
  • self-build-src - native
  • self-compiler - native
  • ts-pre-modules - native
  • vscode - native
  • webpack - native
  • xstate-main - native
Benchmark Name Iterations
Current pr 6
Baseline baseline 6

Developer Information:

Download Benchmarks

@ahejlsberg

This comment was marked as duplicate.

@typescript-automation

This comment was marked as duplicate.

@jakebailey

This comment was marked as duplicate.

@typescript-automation

This comment was marked as duplicate.

@ahejlsberg

Copy link
Copy Markdown
Member Author

Not understanding why typescript-bot is refusing to run the top400 tests.

@jakebailey

Copy link
Copy Markdown
Member

@typescript-bot test top400

1 similar comment
@jakebailey

Copy link
Copy Markdown
Member

@typescript-bot test top400

@typescript-automation

typescript-automation Bot commented Jun 22, 2026

Copy link
Copy Markdown

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

Command Status Results
test top400 ✅ Started ✅ Results

@typescript-automation

Copy link
Copy Markdown

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

Everything looks good!

@ahejlsberg ahejlsberg added this to the TypeScript 7.0 Stable milestone Jun 23, 2026
@DanielRosenwasser

Copy link
Copy Markdown
Member

@typescript-bot test top1000

@typescript-automation

typescript-automation Bot commented Jun 23, 2026

Copy link
Copy Markdown

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

Command Status Results
test top1000 ✅ Started ✅ Results

@typescript-automation

Copy link
Copy Markdown

@DanielRosenwasser Here are the results of running the top 400 repos with tsc comparing main and refs/pull/4389/merge:

Everything looks good!

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.

Inference fails form unions of arrays of different depths (T[] | T[][])

5 participants