File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 11package checker
22
33import (
4+ "math/bits"
45 "slices"
56 "strconv"
67 "strings"
@@ -2869,10 +2870,29 @@ func (c *Checker) isTypeSubsetOf(source *Type, target *Type) bool {
28692870
28702871func (c * Checker ) isTypeSubsetOfUnion (source * Type , target * Type ) bool {
28712872 if source .flags & TypeFlagsUnion != 0 {
2872- for _ , t := range source .Types () {
2873- if ! containsType (target .Types (), t ) {
2873+ sourceTypes , targetTypes := source .Types (), target .Types ()
2874+ if len (sourceTypes ) > len (targetTypes ) {
2875+ return false
2876+ }
2877+ // Scan by identity unless a few source types are looked for in a large target. A CompareTypes call costs
2878+ // roughly 8 pointer comparisons, so there a binary search is cheaper than walking the target.
2879+ if len (sourceTypes )* bits .Len (uint (len (targetTypes )))* 8 >= len (targetTypes ) {
2880+ for _ , t := range sourceTypes {
2881+ i := slices .Index (targetTypes , t )
2882+ if i < 0 {
2883+ return false
2884+ }
2885+ // Union types are sorted by CompareTypes, so the next source type can only appear after this one.
2886+ targetTypes = targetTypes [i + 1 :]
2887+ }
2888+ return true
2889+ }
2890+ for _ , t := range sourceTypes {
2891+ i , found := slices .BinarySearchFunc (targetTypes , t , CompareTypes )
2892+ if ! found {
28742893 return false
28752894 }
2895+ targetTypes = targetTypes [i + 1 :]
28762896 }
28772897 return true
28782898 }
You can’t perform that action at this time.
0 commit comments