Optimize narrowTypeByEquality and narrowTypeBySwitchOnDiscriminant - #4781
Optimize narrowTypeByEquality and narrowTypeBySwitchOnDiscriminant#4781ahejlsberg wants to merge 6 commits into
narrowTypeByEquality and narrowTypeBySwitchOnDiscriminant#4781Conversation
|
@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 | ||
| } | ||
| } |
|
@ahejlsberg Here they are:
tscComparison Report - baseline..pr
System info unknown
Hosts
Scenarios
Developer Information: |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@ahejlsberg Here are the results of running the top 400 repos with tsc comparing Everything looks good! |
|
@typescript-bot perf test this faster |
|
@ahejlsberg Here they are:
tscComparison Report - baseline..pr
System info unknown
Hosts
Scenarios
Developer Information: |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@typescript-bot perf test this faster |
|
@ahejlsberg Here they are:
tscComparison Report - baseline..pr
System info unknown
Hosts
Scenarios
Developer Information: |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@typescript-bot perf test this faster |
|
@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) { |
| 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.
Inspired by the performance gains in #4711, this PR further optimizes union type narrowing in control flow analysis.