Repository navigation
Optimize narrowTypeByEquality and narrowTypeBySwitchOnDiscriminant - #4781
Conversation
|
TypeScript Bot (@typescript-bot) test it |
There was a problem hiding this comment.
Pull request overview
Optimizes primitive-union narrowing during control-flow analysis.
Changes:
- Adds fast paths for equality and switch narrowing.
- Optimizes type removal and centralizes union membership checks.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
internal/checker/flow.go |
Adds narrowing fast paths. |
internal/checker/checker.go |
Optimizes union helpers and type removal. |
| filteredType := c.removeType(t, c.getRegularTypeOfLiteralType(valueType)) | ||
| if filteredType != t { | ||
| return filteredType |
| if !doubleEquals && t.objectFlags&ObjectFlagsPrimitiveUnion != 0 && valueType.flags&TypeFlagsPrimitive != 0 { | ||
| regularType := c.getRegularTypeOfLiteralType(valueType) | ||
| if c.unionContainsType(t, regularType) { | ||
| return regularType | ||
| } | ||
| } |
| if t.objectFlags&ObjectFlagsPrimitiveUnion != 0 && discriminantType.flags&TypeFlagsPrimitive != 0 { | ||
| regularType := c.getRegularTypeOfLiteralType(discriminantType) | ||
| if c.unionContainsType(t, regularType) { | ||
| caseType = regularType | ||
| } | ||
| } |
|
Anders Hejlsberg (@ahejlsberg) Here they are:
tscComparison Report - baseline..pr
System info unknown
Hosts
Scenarios
Developer Information: |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Anders Hejlsberg (@ahejlsberg) Here are the results of running the top 400 repos with tsc comparing Everything looks good! |
|
TypeScript Bot (@typescript-bot) perf test this faster |
|
Anders Hejlsberg (@ahejlsberg) Here they are:
tscComparison Report - baseline..pr
System info unknown
Hosts
Scenarios
Developer Information: |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
TypeScript Bot (@typescript-bot) perf test this faster |
|
Anders Hejlsberg (@ahejlsberg) Here they are:
tscComparison Report - baseline..pr
System info unknown
Hosts
Scenarios
Developer Information: |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
TypeScript Bot (@typescript-bot) perf test this faster |
|
Anders Hejlsberg (@ahejlsberg) Here they are:
tscComparison Report - baseline..pr
System info unknown
Hosts
Scenarios
Developer Information: |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
🟡 Not ready to approve
The fast paths introduce incorrect narrowing for computed enums and non-primitive union constituents.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.
Review details
Comments suppressed due to low confidence (1)
internal/checker/flow.go:1129
- This shortcut never applies to grouped case labels. Their
discriminantTypeis a union, whose flags do not includeTypeFlagsPrimitive, andunionContainsTypewould in any event look for that whole union as one direct constituent. Large switches with many empty fallthrough labels therefore still use the O(union constituents × grouped cases) relational fallback. Check membership for each regular discriminant constituent instead, and cover a grouped-case switch in the performance regression.
if t.objectFlags&ObjectFlagsPrimitiveUnion != 0 && discriminantType.flags&TypeFlagsPrimitive != 0 && c.isUniformUnionType(t) {
regularType := c.getRegularTypeOfLiteralType(discriminantType)
if c.unionContainsType(t, regularType, false /*matchSymbol*/) {
caseType = regularType
- Files reviewed: 8/8 changed files
- Comments generated: 2
- Review effort level: Medium
We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.
| return c.replacePrimitivesWithLiterals(filteredType, valueType) | ||
| } | ||
| if isUnitType(valueType) { | ||
| if c.isUniformUnionType(t) { |
There was a problem hiding this comment.
Yup, an oversight.
| var enumSymbol *ast.Symbol | ||
| var hasStringOrNumberLiteral bool | ||
| for _, t := range types { | ||
| if t.flags&TypeFlagsEnumLiteral != 0 { |
There was a problem hiding this comment.
We all hate that rule, but yeah.
There was a problem hiding this comment.
🟡 Not ready to approve
The primitive-union guard needs regression coverage for intersection constituents.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.
Review details
Comments suppressed due to low confidence (2)
internal/checker/checker.go:27797
- Add the missing “if” to make this sentence grammatical.
internal/checker/checker.go:27801 - The
PrimitiveUnionrestriction added after the reported intersection regression is not exercised by this test suite; all current cases are primitive unions. Please add a compiler case for"a" | ("a" & { brand: true })and verify that the false branch ofx === "a"remainsnever, so this correctness guard cannot regress unnoticed.
- Files reviewed: 8/8 changed files
- Comments generated: 0 new
- Review effort level: Medium
We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.
I don't think so. Plenty of other stuff already depends on primitive-union not including intersection constituents. |
Jake Bailey (jakebailey)
left a comment
There was a problem hiding this comment.
Hate to use up two more flags but I also like to go fast
Inspired by the performance gains in #4711, this PR further optimizes union type narrowing in control flow analysis.